package com.bruce.tool.quartz.core;

import com.bruce.tool.common.exception.ExceptionUtils;
import com.bruce.tool.quartz.domain.QuartzEntity;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 功能 :
 * CRUD
 * @author : Bruce(刘正航) 15:43 2019-02-20
 */
@Slf4j
@Component
public class QuartzService {

    @Autowired
    @Qualifier("Scheduler")
    private Scheduler scheduler;

    public void save(QuartzEntity quartz){
        try {
            //获取Scheduler实例、废弃、使用自动注入的scheduler、否则spring的service将无法注入
            //Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

            // 触发时间点
            CronExpression cronExpression = new CronExpression(quartz.getCronExpression());

            Class cls = Class.forName(quartz.getJobClassName()) ;

            //如果是修改  展示旧的 任务
            if(quartz.getOldJobGroup()!=null){
                JobKey key = new JobKey(quartz.getOldJobName(),quartz.getOldJobGroup());
                scheduler.deleteJob(key);
            }

            //构建job信息
            JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(),
                    quartz.getJobGroup())
                    .usingJobData("triggerUrl",quartz.getTriggerUrl())
                    .usingJobData("statusUrl",quartz.getStatusUrl())
                    .withDescription(quartz.getDescription()).build();
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withDescription(quartz.getCronExpression())
                    .withIdentity(quartz.getTriggerName(), quartz.getJobGroup())
                    .startNow().withSchedule(cronScheduleBuilder).build();
            //交由Scheduler安排触发
            scheduler.scheduleJob(job, trigger);
        } catch (ParseException|SchedulerException|ClassNotFoundException e) {
            ExceptionUtils.printStackTrace(e);
        }
    }

    public void delete(String jobName,String jobGroup){
        try {

            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
            // 停止触发器
            scheduler.pauseTrigger(triggerKey);
            // 移除触发器
            scheduler.unscheduleJob(triggerKey);
            // 删除任务
            scheduler.deleteJob(JobKey.jobKey(jobName, jobGroup));

        } catch (SchedulerException e) {
            ExceptionUtils.printStackTrace(e);
        }
    }

    public List<QuartzEntity> findAll(){
        List<QuartzEntity> list = new ArrayList<>();
        try {
            GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
            Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
            getJobs(jobKeys, list);
        } catch (SchedulerException e) {
            ExceptionUtils.printStackTrace(e);
        }
        return list;
    }

    public void trigger(String jobName,String jobGroup){
        try {
            JobKey key = new JobKey(jobName,jobGroup);
            scheduler.triggerJob(key);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    public void pause(String jobName,String jobGroup){
        try {
            JobKey key = new JobKey(jobName,jobGroup);
            scheduler.pauseJob(key);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    public void resume(String jobName,String jobGroup){
        try {
            JobKey key = new JobKey(jobName,jobGroup);
            scheduler.resumeJob(key);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**获取任务列表**/
    private void getJobs(Set<JobKey> jobKeys, List<QuartzEntity> list) throws SchedulerException {
        for (JobKey jobKey : jobKeys) {
            List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
            for (Trigger trigger : triggers) {
                QuartzEntity job = new QuartzEntity();
                job.setJobName(jobKey.getName());
                job.setJobGroup(jobKey.getGroup());
                JobDetail jobDetail = scheduler.getJobDetail(jobKey);

                String className = jobDetail.getJobClass().getName();
                job.setJobClassName(className);
                job.setDescription(jobDetail.getDescription());
                String triggerUrl = jobDetail.getJobDataMap().getString("triggerUrl");
                String statusUrl = jobDetail.getJobDataMap().getString("statusUrl");
                job.setTriggerUrl(triggerUrl);
                job.setStatusUrl(statusUrl);
                Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                job.setTriggerState(triggerState.name());
                if (trigger instanceof CronTrigger) {
                    CronTrigger cronTrigger = (CronTrigger) trigger;
                    String cronExpression = cronTrigger.getCronExpression();
                    job.setCronExpression(cronExpression);
                    job.setTriggerName(trigger.getKey().getName());
                }
                list.add(job);
            }
        }
    }

}
